<template>
  <div class="page-view">
    <el-form ref="dataForm" :rules="rules" :model="dataForm" label-width="80px" size="small" @change="()=>{
      console.log('东莞')
    }">
      <el-form-item label="" prop="name">
        <template slot="label">
          <span>规则内容</span>
          <div style="line-height: 14px; font-size: 16px; cursor: pointer">
            <i class="el-icon-question"></i>
          </div>
        </template>
        <el-input v-model="dataForm.name"></el-input>
      </el-form-item>

      <el-collapse v-model="collapseActive" accordion class="collapse-area">
        <el-collapse-item :name="1">
          <template slot="title">
            <div>更多规则信息</div>
          </template>
          <el-form-item label="活动区域">
            <el-select v-model="dataForm.region" placeholder="请选择活动区域">
              <el-option label="区域一" value="shanghai"></el-option>
              <el-option label="区域二" value="beijing"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="活动性质">
            <el-checkbox-group v-model="dataForm.type">
              <el-checkbox-button label="美食/餐厅线上活动" name="type"></el-checkbox-button>
              <el-checkbox-button label="地推活动" name="type"></el-checkbox-button>
              <el-checkbox-button label="线下主题活动" name="type"></el-checkbox-button>
            </el-checkbox-group>
          </el-form-item>
          <el-form-item label="特殊资源">
            <el-radio-group v-model="dataForm.resource" size="medium">
              <el-radio border label="线上品牌商赞助"></el-radio>
              <el-radio border label="线下场地免费"></el-radio>
            </el-radio-group>
          </el-form-item>
        </el-collapse-item>
      </el-collapse>

      <el-divider content-position="left">
        <span style="font-size: 18px; color: #409EFF">规则特征信息</span>
      </el-divider>

      <el-form-item label="协议类型" prop="protocol">
        <el-select v-model="dataForm.protocol" placeholder="请选择协议类型" style="width: 100%"
                   @change="protocolChange">
          <el-option v-for="option in customProtocolTypeList" :key="option.enumVal2" :label="option.enumVal"
                     :value="option.enumVal2"/>
        </el-select>
      </el-form-item>

      <div class="protocol-attr-box" v-for="(attrItem, attrIndex) in dataForm.featureAttributeNodes"
           :key="attrItem.key">
        <el-form-item
            class="child"
            label=""
            :prop="`featureAttributeNodes[${attrIndex}].attributeName`"
        >
          <el-select clearable v-model="attrItem.attributeName" placeholder="请选择协议属性名"
                     @change="featureAttributeChange(attrItem)">
            <el-option v-for="option in customFeatureAttributeList" :disabled="!!option.disable" :key="option.enumVal2"
                       :label="option.enumVal"
                       :value="option.enumVal2"/>
          </el-select>
        </el-form-item>

        <div class="child"></div>

        <template>
          <el-form-item
              v-if="attrItem.attributeName === 't'"
              class="child"
              label=""
              :prop="`featureAttributeNodes[${attrIndex}].attributeVal`"
          >
            <el-select v-model="attrItem.attributeVal" placeholder="请选择属性值" style="width: 100%">
              <el-option
                  v-for="subItem in customProtocolTypeSubTypeList"
                  :key="subItem.enumKey"
                  :label="subItem.enumVal"
                  :value="subItem.enumVal2">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item
              v-else-if="attrItem.attributeName === 'count'"
              class="child"
              label=""
              :prop="`featureAttributeNodes[${attrIndex}].attributeVal`"
          >
            <el-input-number style="width: 100%" v-model="attrItem.attributeVal" :precision="0" :step="1"
                             :min="1"></el-input-number>
          </el-form-item>
          <el-form-item
              v-else-if="attrItem.attributeName === 'wbase'"
              class="child"
              label=""
              :prop="`featureAttributeNodes[${attrIndex}].attributeVal`"
          >
            <el-input-number style="width: 100%" v-model="attrItem.attributeVal" :precision="0" :step="1" :min="0"
                             :max="10"></el-input-number>
          </el-form-item>
          <el-form-item
              v-else-if="attrItem.attributeName === 'o'"
              class="child"
              label=""
              :prop="`featureAttributeNodes[${attrIndex}].attributeVal`"
          >
            <el-select v-model="attrItem.attributeVal" placeholder="请选择属性值" style="width: 100%" multiple collapse-tags>
              <el-option v-for="option in attributeOList" :label="option.label" :value="option.value"
                         :key="option.value"/>
            </el-select>
          </el-form-item>
          <el-form-item
              v-else-if="attrItem.attributeName === 'fin'"
              class="child"
              label=""
          >
            <el-checkbox v-model="attrItem.attributeVal">相同检测引擎/检测点下的其他特征不再执行检测</el-checkbox>
          </el-form-item>
          <el-form-item
              v-else-if="attrItem.attributeName === 'piority'"
              class="child"
              label=""
              :prop="`featureAttributeNodes[${attrIndex}].attributeVal`"
          >
            <el-input-number style="width: 100%" v-model="attrItem.attributeVal" :precision="0" :step="1" :min="-6"
                             :max="6"></el-input-number>
          </el-form-item>
          <el-form-item
              v-else-if="attrItem.attributeName === 'repeat'"
              class="child"
              label=""
              :prop="`featureAttributeNodes[${attrIndex}].attributeVal`"
          >
            <el-radio-group v-model="attrItem.attributeVal">
              <el-radio :label="0">关闭</el-radio>
              <el-radio :label="1">开启</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item
              v-else
              class="child"
              label=""
              :prop="`featureAttributeNodes[${attrIndex}].attributeVal`"
          >
            <el-input v-model="attrItem.attributeVal" placeholder="请输入属性值"></el-input>
          </el-form-item>
        </template>

        <div class="child">
          <el-button type="danger" size="mini" icon="el-icon-minus" circle
                     v-if="attrIndex>0 || dataForm.featureAttributeNodes.length>1"
                     @click.stop="deleteFeatureAttributeNodes(attrIndex)"></el-button>
          <el-button type="primary" size="mini" icon="el-icon-plus" circle
                     v-if="(attrIndex + 1) === dataForm.featureAttributeNodes.length"
                     @click.stop="addFeatureAttributeNodes"
          ></el-button>
        </div>
      </div>

      <div class="protocol-attr-box" v-for="(attrItem, attrIndex) in dataForm.featureActionNodes" :key="attrItem.key">
        <el-form-item
            class="child"
            :label="!attrIndex ? '特征动作':''"
            :prop="`featureActionNodes[${attrIndex}].attributeName`"
            :rules="{ required: true, message: '请选动作属性名', trigger: 'change' }"
        >
          <el-select clearable v-model="attrItem.attributeName" placeholder="请选动作属性名"
                     @change="featureActionChange(attrItem)">
            <el-option v-for="option in customFeatureActionList" :disabled="!!option.disable" :key="option.enumVal2"
                       :label="option.enumVal"
                       :value="option.enumVal2"/>
          </el-select>
        </el-form-item>

        <div class="child"></div>

        <template>
          <el-form-item
              v-if="attrItem.attributeName === 'pcap'"
              class="child"
              label=""
              :prop="`featureActionNodes[${attrIndex}].attributeVal`"
              :rules="{
                    required: true, message: '请选择属性值', trigger: 'blur'
                  }"
          >
            <el-radio-group v-model="attrItem.attributeVal">
              <el-radio :label="0">关闭</el-radio>
              <el-radio :label="1">开启</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item
              v-else
              class="child"
              label=""
              :prop="`featureActionNodes[${attrIndex}].attributeVal`"
              :rules="{
                    required: true, message: '请输入属性值', trigger: 'blur'
                  }"
          >
            <el-input v-model="attrItem.attributeVal" placeholder="请输入属性值"></el-input>
          </el-form-item>
        </template>

        <div class="child">
          <el-button type="danger" size="mini" icon="el-icon-minus" circle
                     v-if="attrIndex>0 || dataForm.featureActionNodes.length>1"
                     @click.stop="deleteFeatureActionNodes(attrIndex)"></el-button>
          <el-button type="primary" size="mini" icon="el-icon-plus" circle
                     v-if="(attrIndex + 1) === dataForm.featureActionNodes.length"
                     @click.stop="addFeatureActionNodes"
          ></el-button>
        </div>
      </div>

      <!--含有子节点循环的 -->
      <div style="font-size: 14px;padding-left: 2px; color: #606266; margin-bottom: 10px">
        <span style=" margin-right: 3px; color: #F56C6C">*</span>
        <span>特征规则</span>
      </div>
      <div class="protocol-area" v-for="(item, index) in dataForm.featureRuleNodes" :key="item.key">

        <div class="protocol-box">
          <el-form-item
              :label="'节点' + (index+1)"
              :prop="`featureRuleNodes[${index}].nodeVal`"
              :rules="{ required: true, message: '请选择节点', trigger: 'change' }"
          >
            <el-select v-model="item.nodeVal" placeholder="请选择节点" style="width: 100%">
              <el-option label="ci（content inspect 内容匹配)" value="ci"/>
            </el-select>
          </el-form-item>

          <div class="child-title">
            <div>
              <span style="color: red; margin-right: 3px">*</span>
              <span>规则属性</span>
            </div>
          </div>
          <div class="child-box">
            <div class="protocol-attr-box" v-for="(attrItem, attrIndex) in item.attributes" :key="attrItem.key">

              <el-form-item
                  class="child"
                  label=""
                  :prop="`featureRuleNodes[${index}].attributes[${attrIndex}].attributeName`"
                  :rules="{ required: true, message: '请选择规则属性名', trigger: 'change' }"
              >
                <el-select clearable v-model="attrItem.attributeName" placeholder="请选择规则属性名"
                           @change="((val)=>{featureRuleAttrChange(attrItem, index)})">
                  <el-option v-for="option in item.selectList" :disabled="!!option.disable" :key="option.enumVal2"
                             :label="option.enumVal"
                             :value="option.enumVal2"/>
                </el-select>
              </el-form-item>

              <div class="child"></div>

              <template>
                <el-form-item
                    v-if="attrItem.attributeName === 'o'"
                    class="child"
                    label=""
                    :prop="`featureRuleNodes[${index}].attributes[${attrIndex}].attributeVal`"
                    :rules="{
                  required: true, message: '请选择属性值', trigger: 'change'
                }"
                >
                  <el-select v-model="attrItem.attributeVal" placeholder="请选择属性值" style="width: 100%" multiple collapse-tags>
                    <el-option v-for="option in attributeOList" :label="option.label" :value="option.value"
                               :key="option.value"/>
                  </el-select>
                </el-form-item>

                <el-form-item
                    v-else-if="attrItem.attributeName === 't'"
                    class="child"
                    label=""
                    :prop="`featureRuleNodes[${index}].attributes[${attrIndex}].attributeVal`"
                    :rules="{
                  required: true, message: '请选择属性值', trigger: 'change'
                }"
                >
                  <el-select v-model="attrItem.attributeVal" placeholder="请选择属性值" style="width: 100%">
                    <el-option
                        v-for="subItem in customProtocolTypeSubTypeList"
                        :key="subItem.enumKey"
                        :label="subItem.enumVal"
                        :value="subItem.enumVal2">
                    </el-option>
                  </el-select>
                </el-form-item>

                <el-form-item
                    v-else-if="attrItem.attributeName === 'w'"
                    class="child"
                    label=""
                    :prop="`featureRuleNodes[${index}].attributes[${attrIndex}].attributeVal`"
                    :rules="{
                    required: true, message: '请输入属性值', trigger: 'blur'
                  }"
                >
                  <el-input-number style="width: 100%" v-model="attrItem.attributeVal" :precision="0" :step="1" :min="1"
                                   :max="10"></el-input-number>
                </el-form-item>

                <el-form-item
                    v-else-if="attrItem.attributeName === 'regset'"
                    class="child"
                    label=""
                    :prop="`featureRuleNodes[${index}].attributes[${attrIndex}].attributeVal`"
                    :rules="{
                    required: true, message: '请输入属性值', trigger: 'blur'
                  }"
                >
                  <el-input-number style="width: 100%" v-model="attrItem.attributeVal" :precision="0" :step="1" :min="0"
                                   :max="4"></el-input-number>
                </el-form-item>

                <el-form-item
                    v-else
                    class="child"
                    label=""
                    :prop="`featureRuleNodes[${index}].attributes[${attrIndex}].attributeVal`"
                    :rules="{
                    required: true, message: '请输入属性值', trigger: 'blur'
                  }"
                >
                  <el-input v-model="attrItem.attributeVal" placeholder="请输入属性值"></el-input>
                </el-form-item>
              </template>

              <div class="child">
                <el-button type="danger" size="mini" icon="el-icon-minus" circle
                           v-if="attrIndex>0 || item.attributes.length>1"
                           @click.stop="deleteFeatureRuleAttrNodes(item.selectList,item.attributes, attrIndex, index)"></el-button>
                <el-button type="primary" size="mini" icon="el-icon-plus" circle
                           v-if="(attrIndex + 1) === item.attributes.length"
                           @click.stop="addFeatureRuleAttrNodes(item.attributes)"></el-button>
              </div>
            </div>
          </div>

          <div class="child-title">
            <div>
              <span style="color: red; margin-right: 3px">*</span>
              <span>子节点</span>
            </div>
            <el-button type="primary" size="mini" icon="el-icon-plus"
                       @click.stop="addChildByFeatureRule(item.childrenNodes)">添加子节点
            </el-button>
          </div>
          <div class="grandson-area" v-for="(sonItem, sonIndex) in item.childrenNodes">
            <ul class="grandson-box">
              <li>
                <el-form-item
                    label=""
                    :prop="`featureRuleNodes[${index}].childrenNodes[${sonIndex}].childNodeVal`"
                >
                  <el-select v-model="sonItem.childNodeVal" clearable @change="(val)=>{
                    ganDeChildNodeChange(val,sonItem);
                  }">
                    <el-option v-for="gOption in ganDeChildNodeList" :label="gOption.label" :value="gOption.value"/>
                  </el-select>
                </el-form-item>
              </li>
              <li style="margin-left: 20px;">
                <div v-for="(gandeItem, gandeIndex) in sonItem.childAttributes"
                     style="display:flex; align-items: center; margin-bottom: 15px">
                  <el-form-item
                      label=""
                      :prop="`featureRuleNodes[${index}].childrenNodes[${sonIndex}].childAttributes[${gandeIndex}].childAttrName`"
                  >
                    <el-select v-model="gandeItem.childAttrName" clearable @change="(val) =>{
                        ganDeChildAttrChange(val, gandeItem)
                      }">
                      <el-option v-for="gOption in sonItem.childAttrSelList" :label="gOption.label"
                                 :value="gOption.value"/>
                    </el-select>
                  </el-form-item>

                  <div style="width: 30px; height: 1px; background: #ccc"></div>

                  <template>
                    <el-form-item
                        label=""
                        :prop="`featureRuleNodes[${index}].childrenNodes[${sonIndex}].childAttributes[${gandeIndex}].childAttrVal`"
                    >
                      <template v-if="loadIncludes(['offset', 'lb', 'ub'], gandeItem.childAttrName)">
                        <el-input-number style="width: 100%" v-model="gandeItem.childAttrVal" :precision="0" :step="1" :min="1"
                        ></el-input-number>
                      </template>
                      <template v-else-if="loadIncludes(['bt', 'lt'], sonItem.childNodeVal) && gandeItem.childAttrName === 'val'">
                        <el-input-number style="width: 100%" v-model="gandeItem.childAttrVal" :precision="0" :step="1" :min="1"
                        ></el-input-number>
                      </template>
                      <template v-else-if="loadIncludes(['ex', 'regset'], gandeItem.childAttrName)">
                        <el-input-number style="width: 100%" v-model="gandeItem.childAttrVal" :precision="0" :step="1"
                        ></el-input-number>
                      </template>
                      <template v-else-if="sonItem.childNodeVal === 'be' && gandeItem.childAttrName === 'o'">
                        <el-select v-model="gandeItem.childAttrVal" clearable multiple collapse-tags>
                          <el-option v-for="ooption in genDeAttrValO1List" :label="ooption.label"
                                     :value="ooption.value"/>
                        </el-select>
                      </template>
                      <template v-else-if="loadIncludes(['bt', 'bb','lcr-ex','extract', 'export'], sonItem.childNodeVal) && gandeItem.childAttrName === 'o'">
                        <el-select v-model="gandeItem.childAttrVal" clearable multiple collapse-tags>
                          <el-option v-for="ooption in genDeAttrValO2List" :label="ooption.label"
                                     :value="ooption.value"/>
                        </el-select>
                      </template>
                      <template v-else-if="sonItem.childNodeVal === 'match' && gandeItem.childAttrName === 'o'">
                        <el-select v-model="gandeItem.childAttrVal" clearable multiple collapse-tags>
                          <el-option v-for="ooption in genDeAttrValO3List" :label="ooption.label"
                                     :value="ooption.value"/>
                        </el-select>
                      </template>
                      <template v-else-if="sonItem.childNodeVal === 'pcre' && gandeItem.childAttrName === 'o'">
                        <el-select v-model="gandeItem.childAttrVal" clearable multiple collapse-tags>
                          <el-option v-for="ooption in genDeAttrValO4List" :label="ooption.label"
                                     :value="ooption.value"/>
                        </el-select>
                      </template>
                      <template v-else-if="gandeItem.childAttrName === 'r'">
                        <el-select v-model="gandeItem.childAttrVal" clearable>
                          <el-option v-for="ooption in genDeAttrValRList" :label="ooption.label"
                                     :value="ooption.value"/>
                        </el-select>
                      </template>
                      <template v-else-if="gandeItem.childAttrName === 'type'">
                        <el-select v-model="gandeItem.childAttrVal" clearable>
                          <el-option v-for="ooption in genDeAttrValTypeList" :label="ooption.label"
                                     :value="ooption.value"/>
                        </el-select>
                      </template>
                      <template v-else-if="loadIncludes(['encode'], gandeItem.childAttrName)">
                        <el-radio-group v-model="gandeItem.childAttrVal">
                          <el-radio :label="0">关闭</el-radio>
                          <el-radio :label="1">开启</el-radio>
                        </el-radio-group>
                      </template>

                      <template v-else>
                        <el-input v-model="gandeItem.childAttrVal"></el-input>
                      </template>
                    </el-form-item>
                  </template>

                  <div style="margin-left: 20px">
                    <el-button type="danger" size="mini" icon="el-icon-minus" circle
                               v-if="gandeIndex>0 || sonItem.childAttributes.length>1"
                               @click.stop="gandeDeleteByFeatureRule(sonItem.childAttributes, gandeIndex)"></el-button>
                    <el-button type="primary" size="mini" icon="el-icon-plus" circle
                               v-if="(gandeIndex + 1) === sonItem.childAttributes.length"
                               @click.stop="gandeAddByFeatureRule(sonItem.childAttributes)"></el-button>
                  </div>

                </div>
              </li>
            </ul>
            <div style="margin-left: 20px" v-if="sonIndex > 0 || item.childrenNodes.length>1">
              <el-button type="danger" icon="el-icon-delete" circle
                         @click.stop="deleteChildByFeatureRule(item.childrenNodes, sonIndex)"></el-button>
            </div>
          </div>

        </div>

        <div style="margin-left: 20px" v-if="index>0 || dataForm.featureRuleNodes.length > 1">
          <el-button type="danger" icon="el-icon-delete" plain @click.stop="deleteFeatureRuleNodes(index);">删除
          </el-button>
        </div>
      </div>

      <div class="add-node">
        <el-button type="primary" icon="el-icon-plus" style="width: 100%" size="small" plain
                   @click.stop="addFeatureRuleNodes">添加节点
        </el-button>
      </div>


      <el-form-item>
        <el-button type="primary" @click="onSubmit">立即创建</el-button>
        <el-button @click="reset">取消</el-button>
      </el-form-item>

      <el-button type="primary" @click="getCustomList">表单赋值</el-button>
      <el-button type="primary" @click="setRuleContent">生成规则</el-button>
    </el-form>

    <!--    <Hello></Hello>-->

    <!--    <div>{{fullName}}</div>-->

    <code style="font-size: 14px; font-weight: bold">{{ dataForm.customFeature }}</code>



  </div>
</template>

<script>
import Hello from './Hello.vue';
import {cloneDeep, find, intersection, includes} from 'lodash'
import {
  getOptions,
  genDeAttrValO1List,
  genDeAttrValO2List,
  genDeAttrValO3List,
  genDeAttrValO4List,
  genDeAttrValRList,
  genDeAttrValTypeList
} from './useOptions.js'

export default {
  // 特征规则下拉框数据

  data() {
    return {
      dataForm: {
        name: '',
        region: '',
        delivery: false,
        type: [],
        resource: '',
        desc: '',


        // 存规则所有字段的JSON
        customFeatureJson: '',
        // 协议类型 protocol
        protocol: null,
        // 协议-特征属性 protocol-attr
        featureAttributeNodes: [{
          key: new Date().getTime() + 2,
          attributeName: '',
          attributeVal: ''
        }],
        // 特征动作 Action
        featureActionNodes: [{
          key: new Date().getTime() + 3,
          attributeName: '',
          attributeVal: ''
        }],
        // 特征规则 ci
        featureRuleNodes: [{
          selectList: [],
          nodeVal: 'ci',
          key: new Date().getTime(),
          attributes: [{
            attributeName: '',
            key: new Date().getTime(),
            attributeVal: ''
          }],
          childrenNodes: [{
            childNodeVal: '',
            // 子节点中的属性下拉框数据
            childAttrSelList: [],
            childAttributes: [{
              childAttrName: '',
              childAttrVal: '',
            }]
          }]
        }],
        customFeature: '',
      },
      rules: {
        name: [
          {required: true, message: '请输入活动名称', trigger: 'blur'},
        ],
        protocol: [
          {required: true, message: '请选择协议类型', trigger: 'change'},
        ]
      },

      // 折叠面板
      collapseActive: 0,
      // 协议下拉列表
      customProtocolTypeList: [],
      // 协议子类下拉列表
      customProtocolTypeSubTypeList: [],
      //特征规则下拉框数据
      customFeatureRuleList: [],
      // 协议属性下拉框数据
      customFeatureAttributeList: [],
      // 协议动作下拉框数据
      customFeatureActionList: [],
      // T规则下拉框数据
      attributeOList: [
        {
          value: 'packet',
          label: 'packet'
        }, {
          value: 'emit',
          label: '命中时创建上下文（emit）'
        }, {
          value: 'block',
          label: '段/包内偏移（block）'
        }, {
          value: 'i',
          label: '忽略大小写(i)'
        }, {
          value: 'nocount',
          label: '命中时不参与计数(nocount)'
        }
      ],

      //子节点下拉框数据
      ganDeChildNodeList: [
        {
          value: 'fi',
          label: 'fi'
        },
        {
          value: 'be',
          label: '检查字节是否符合设定值（be）'
        },
        {
          value: 'bt',
          label: '检查字节与预期的相对关系（bt）'
        },
        {
          value: 'bb',
          label: '检查特定位置和范围的内容（bb）'
        },
        {
          value: 'lt',
          label: '检查块长度与预期的相对关系（lt）'
        },
        {
          value: 'lcr',
          label: '检查块长度存在特定计算关系的值（lcr）'
        },
        {
          value: 'lcr-ex',
          label: '检查块长度存在特定计算关系的值（lcr-ex）'
        },
        {
          value: 'ccr',
          label: '检查特定位置上存在特定关系的值（ccr）'
        },
        {
          value: 'port',
          label: '检查连接的端口是否满足预期（port）'
        },
        {
          value: 'portng',
          label: '检查连接的端口是否满足预期范围（portng）'
        },
        {
          value: 'match',
          label: '进一步匹配二进制内容（match）'
        },
        {
          value: 'pcre',
          label: '执行pcre规则语法的检测（pcre）'
        },
        {
          value: 'extract',
          label: '偏移特定宽度的内容保存到标定点（extract）'
        },
        {
          value: 'export',
          label: '特定内容保存到检测上下文（export）'
        },
      ],
      genDeAttrValO1List,
      genDeAttrValO2List,
      genDeAttrValO3List,
      genDeAttrValO4List,
      genDeAttrValRList,
      genDeAttrValTypeList
    };
  },
  components: {
    Hello
  },
  created() {
    this.init();
  },
  watch: {
    'dataForm.protocol': {
      handler(){
        this.setRuleContent();
      },
      deep: true
    },
    'dataForm.featureAttributeNodes': {
      handler(){
        this.setRuleContent();
      },
      deep: true
    },
    'dataForm.featureActionNodes': {
      handler(){
        this.setRuleContent();
      },
      deep: true
    },
    'dataForm.featureRuleNodes': {
      handler(){
        this.setRuleContent();
      },
      deep: true
    }
  },
  methods: {
    loadIncludes: includes,
    init() {
      this.customProtocolTypeList = [
        {
          "id": "5850905e48484fb89cd5947f67b009ff",
          "enumKey": "1",
          "enumVal": "tcp",
          "enumSeq": 1,
          "enumType": "customProtocolType",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "tcp",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "caf0ae3d5ae8473fa4edce72066442b3",
          "enumKey": "2",
          "enumVal": "udp",
          "enumSeq": 2,
          "enumType": "customProtocolType",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "udp",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "fe2a404f3c2644c9882ba504f97b7cb6",
          "enumKey": "3",
          "enumVal": "http",
          "enumSeq": 3,
          "enumType": "customProtocolType",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "http",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "9b703e7fe1b14858b44d77f515fa4205",
          "enumKey": "4",
          "enumVal": "ssl",
          "enumSeq": 4,
          "enumType": "customProtocolType",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "ssl",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        }
      ];
      this.customProtocolTypeSubTypeList = [
        {
          "id": "5850905e48484fb89cd5947f67b009ff",
          "enumKey": "1",
          "enumVal": "tosvr",
          "enumSeq": 1,
          "enumType": "customProtocolType",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "tosvr",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "caf0ae3d5ae8473fa4edce72066442b3",
          "enumKey": "2",
          "enumVal": "tocli",
          "enumSeq": 2,
          "enumType": "customProtocolType",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "tocli",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
      ];
      this.customFeatureRuleList = [
        {
          "id": "3e6bce26629f43bdaa65131e48b777f9",
          "enumKey": "1",
          "enumVal": "强制字符串特征（mc）",
          "enumSeq": 1,
          "enumType": "customFeatureRule",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "mc",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "feb16deae1104aa6aaf71b0ae4f4e6e4",
          "enumKey": "2",
          "enumVal": "可选的字符串规则（oc）",
          "enumSeq": 2,
          "enumType": "customFeatureRule",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "oc",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "9d5b4c0791f44b6d8261504886b842b8",
          "enumKey": "3",
          "enumVal": "强制正则规则（mregx）",
          "enumSeq": 3,
          "enumType": "customFeatureRule",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "mregx",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "5c5c0517f7c74eb3935283f4e41b64fa",
          "enumKey": "4",
          "enumVal": "可选的正则规则（oregx）",
          "enumSeq": 4,
          "enumType": "customFeatureRule",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "oregx",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "3aa75ad81f1d4680ac7accc5b4d7709f",
          "enumKey": "5",
          "enumVal": "覆盖规则属性（o）",
          "enumSeq": 5,
          "enumType": "customFeatureRule",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "o",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "99d4ff8c4fb44022927a97e4c4239714",
          "enumKey": "6",
          "enumVal": "检测点约束（t）",
          "enumSeq": 6,
          "enumType": "customFeatureRule",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "t",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "473006f498474e679a0190a4c280d125",
          "enumKey": "7",
          "enumVal": "函数名引入引擎（func）",
          "enumSeq": 7,
          "enumType": "customFeatureRule",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "func",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "43a90ac80c624ace9de6a35398694fa2",
          "enumKey": "8",
          "enumVal": "权重积分（w）",
          "enumSeq": 8,
          "enumType": "customFeatureRule",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "w",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "1888ba40388140b68fa5fea7fa0554c6",
          "enumKey": "9",
          "enumVal": "规则的有效偏移范围（range）",
          "enumSeq": 9,
          "enumType": "customFeatureRule",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "range",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "93f994a36317445f8564c2e6f504c9d0",
          "enumKey": "10",
          "enumVal": "规则命参考点（regset）",
          "enumSeq": 10,
          "enumType": "customFeatureRule",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "regset",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "69f6767f4b3845c69e7072ec215eafc0",
          "enumKey": "11",
          "enumVal": "规则与预设参考点的关系（relative）",
          "enumSeq": 11,
          "enumType": "customFeatureRule",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "relative",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "5e24dac4d02a444891f4d00f7d931421",
          "enumKey": "12",
          "enumVal": "带顺序的强制字符串特征（seq）",
          "enumSeq": 12,
          "enumType": "customFeatureRule",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "seq",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        }
      ];
      this.customFeatureAttributeList = [
        {
          "id": "1240a6e8cf0f48a8a133506c57152bdb",
          "enumKey": "1",
          "enumVal": "检测点（t）",
          "enumSeq": 1,
          "enumType": "customFeatureAttribute",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "t",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "0e69a59c0da34c30a0c5e95e593af4fd",
          "enumKey": "2",
          "enumVal": "规则别名（alias）",
          "enumSeq": 2,
          "enumType": "customFeatureAttribute",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "alias",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "95268f066d574366930023c49f1d18b6",
          "enumKey": "3",
          "enumVal": "计数阈值（count）",
          "enumSeq": 3,
          "enumType": "customFeatureAttribute",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "count",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "dbfe2bb059a04bfb8c34160c8f0b9f18",
          "enumKey": "4",
          "enumVal": "权重阈值（wbase）",
          "enumSeq": 4,
          "enumType": "customFeatureAttribute",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "wbase",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "e200297d07204666971655be1ed8800c",
          "enumKey": "5",
          "enumVal": "特征行为（o）",
          "enumSeq": 5,
          "enumType": "customFeatureAttribute",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "o",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "d48789a7c88d4489a5abe1ede43b3fff",
          "enumKey": "6",
          "enumVal": "停止通知（fin）",
          "enumSeq": 6,
          "enumType": "customFeatureAttribute",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "fin",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "d43d6ed940b4412bb93c936b67f85e2c",
          "enumKey": "7",
          "enumVal": "其他特征关联（parent）",
          "enumSeq": 7,
          "enumType": "customFeatureAttribute",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "parent",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "9b2dda2a86c54038af7b0af4261d7c19",
          "enumKey": "8",
          "enumVal": "优先级（piority）",
          "enumSeq": 8,
          "enumType": "customFeatureAttribute",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "piority",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "2f61e22ca9df48b3aec2550fe56caa46",
          "enumKey": "9",
          "enumVal": "特征id（id）",
          "enumSeq": 9,
          "enumType": "customFeatureAttribute",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "id",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "6a1e1f0ed101418d8bd8932850f71d0b",
          "enumKey": "10",
          "enumVal": "规则重复命中开关（repeat）",
          "enumSeq": 10,
          "enumType": "customFeatureAttribute",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "repeat",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        }
      ];
      this.customFeatureActionList = [
        {
          "id": "76e7e34d3d4f47ecb58543cd79f9af24",
          "enumKey": "1",
          "enumVal": "行为标签（behave）",
          "enumSeq": 1,
          "enumType": "customFeatureAction",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "behave",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "5e9b2f7942d4414da28c3e9afac83e2e",
          "enumKey": "2",
          "enumVal": "协议/应用描述（proto）",
          "enumSeq": 2,
          "enumType": "customFeatureAction",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "proto",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "a13b2540e0a449cbaf39ec0a8746651e",
          "enumKey": "3",
          "enumVal": "协议解析器（parser）",
          "enumSeq": 3,
          "enumType": "customFeatureAction",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "parser",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
        {
          "id": "e1190e4290534e92a549994c9e0a1202",
          "enumKey": "4",
          "enumVal": "抓包标记（pcap）",
          "enumSeq": 4,
          "enumType": "customFeatureAction",
          "parentKey": null,
          "parentType": null,
          "enumVal2": "pcap",
          "enumVal3": null,
          "enumVal4": null,
          "enumVal5": null,
          "disable": 0
        },
      ];
      this.dataForm.featureRuleNodes[0].selectList = cloneDeep(this.customFeatureRuleList)
    },

    getCustomList() {
      const customFeatureJson = '{"protocol":"tcp","featureAttributeNodes":[{"key":1719296111711,"attributeName":"t","attributeVal":"tocli"},{"attributeName":"repeat","key":1719296572711,"attributeVal":1}],"featureActionNodes":[{"key":1719296111712,"attributeName":"proto","attributeVal":"qwe"},{"attributeName":"proto","key":1719296568961,"attributeVal":"dffg"}],"featureRuleNodes":[{"nodeVal":"ci","key":1719296111709,"attributes":[{"attributeName":"t","key":1719296111709,"attributeVal":"tosvr"}]},{"nodeVal":"ci","key":1719296577255,"attributes":[{"attributeName":"mc","key":1719296577255,"attributeVal":"sad"}]}]}'
      const result = JSON.parse(customFeatureJson);
      const {protocol, featureAttributeNodes, featureActionNodes, featureRuleNodes} = result;
      for (const item of featureRuleNodes) {
        item.selectList = cloneDeep(this.customFeatureRuleList)
      }
      this.dataForm.protocol = protocol;
      this.dataForm.featureAttributeNodes = featureAttributeNodes;
      this.dataForm.featureActionNodes = featureActionNodes;
      this.dataForm.featureRuleNodes = featureRuleNodes;
    },

    getCustomFeatureJson() {
      for (const item of this.dataForm.featureRuleNodes) {
        delete item.selectList;
      }
      const result = {
        protocol: this.dataForm.protocol,
        featureAttributeNodes: this.dataForm.featureAttributeNodes,
        featureActionNodes: this.dataForm.featureActionNodes,
        featureRuleNodes: this.dataForm.featureRuleNodes,
      }
      const jsonString = JSON.stringify(result);
      /*delete this.dataForm.protocol;
      delete this.dataForm.featureAttributeNodes;
      delete this.dataForm.featureActionNodes;
      delete this.dataForm.featureRuleNodes;*/
      return jsonString;
    },
    onSubmit() {
      this.$refs.dataForm.validate((valid) => {
        if (valid) {
          this.dataForm.customFeatureJson = this.getCustomFeatureJson();
          console.log(this.dataForm);
        } else {
          return false;
        }
      });
    },


    resetCustomFeatureJson() {
      this.dataForm.customFeatureJson = '';
      this.dataForm.protocol = null;
      this.dataForm.featureAttributeNodes = [{
        key: new Date().getTime() + 4,
        attributeName: '',
        attributeVal: ''
      }];
      this.dataForm.featureActionNodes = [{
        key: new Date().getTime() + 5,
        attributeName: '',
        attributeVal: ''
      }];
      this.dataForm.featureRuleNodes = [{
        selectList: [],
        nodeVal: 'ci',
        key: new Date().getTime(),
        attributes: [{
          attributeName: '',
          key: new Date().getTime(),
          attributeVal: ''
        }],
        childrenNodes: [{
          childNodeVal: '',
          // 子节点中的属性下拉框数据
          childAttrSelList: [],
          childAttributes: [{
            childAttrName: '',
            childAttrVal: '',
          }]
        }]
      }]
    },
    reset() {
      this.$refs.dataForm.resetFields();
      this.resetCustomFeatureJson();
    },

    /* 增加、删除表单项目相关方法~~~~~~~~~*/

    protocolChange(val) {
      const pData = find(this.customProtocolTypeList, (item) => {
        return item.enumVal2 === val;
      })
      console.log(pData)
    },

    /*添加协议属性节点相关方法------*/
    // 添加协议属性中的属性节点
    addFeatureAttributeNodes() {
      this.dataForm.featureAttributeNodes.push({
        attributeName: '',
        key: new Date().getTime() + 2,
        attributeVal: ''
      })
    },
    // 删除协议属性中的属性节点
    deleteFeatureAttributeNodes(index) {
      this.customFeatureAttributeList.forEach((item) => {
        if (item.enumVal2 === this.dataForm.featureAttributeNodes[index].attributeName) {
          item.disable = 0;
        }
      })
      this.dataForm.featureAttributeNodes.splice(index, 1);
    },
    featureAttributeChange(attrItem) {
      attrItem.attributeVal = '';
      for (const listItem of this.customFeatureAttributeList) {
        const selItem = find(this.dataForm.featureAttributeNodes, (obj) => {
          return listItem.enumVal2 === obj.attributeName
        })
        if (selItem) {
          listItem.disable = 1;
        } else {
          listItem.disable = 0;
        }
      }
    },
    /*添加协议属性节点相关方法------*/

    /*添加协议动作节点相关方法------*/
    addFeatureActionNodes() {
      this.dataForm.featureActionNodes.push({
        attributeName: '',
        key: new Date().getTime() + 2,
        attributeVal: ''
      })
    },
    deleteFeatureActionNodes(index) {
      this.customFeatureActionList.forEach((item) => {
        if (item.enumVal2 === this.dataForm.featureActionNodes[index].attributeName) {
          item.disable = 0;
        }
      })
      this.dataForm.featureActionNodes.splice(index, 1);
    },
    featureActionChange(attrItem) {
      attrItem.attributeVal = '';
      for (const listItem of this.customFeatureActionList) {
        const selItem = find(this.dataForm.featureActionNodes, (obj) => {
          return listItem.enumVal2 === obj.attributeName
        })
        if (selItem) {
          listItem.disable = 1;
        } else {
          listItem.disable = 0;
        }
      }
    },
    /*添加协议属性节点相关方法------*/

    /*添加特征规则节点相关方法------*/
    addFeatureRuleNodes() {
      this.dataForm.featureRuleNodes.push({
        selectList: cloneDeep(this.customFeatureRuleList),
        nodeVal: 'ci',
        key: new Date().getTime(),
        attributes: [{
          attributeName: '',
          key: new Date().getTime(),
          attributeVal: ''
        }],
        childrenNodes: [{
          childNodeVal: '',
          // 子节点中的属性下拉框数据
          childAttrSelList: [],
          childAttributes: [{
            childAttrName: '',
            childAttrVal: '',
          }]
        }]
      })
    },
    //  删除特征规则节点
    deleteFeatureRuleNodes(index) {
      this.dataForm.featureRuleNodes.splice(index, 1)
    },
    // 添加特征规则中的属性节点
    addFeatureRuleAttrNodes(attributes) {
      attributes.push({
        attributeName: '',
        key: new Date().getTime(),
        attributeVal: ''
      })
    },
    // 删除特征规则中的属性节点
    deleteFeatureRuleAttrNodes(selectList, attributes, attrIndex, index) {
      selectList.forEach((item) => {
        if (item.enumVal2 === attributes[attrIndex].attributeName) {
          item.disable = 0;
        }
      })
      attributes.splice(attrIndex, 1);
      this.featureRuleAttrChange(attributes[attrIndex], index);
    },
    // 特征规则中的属性选中改变事件
    featureRuleAttrChange(attrItem, index) {
      attrItem ? attrItem.attributeVal = '' : null;
      const disableArray = ['mc', 'oc', 'mregx', 'oregx', 'seq'];
      const featureRuleNode = this.dataForm.featureRuleNodes[index];

      for (const listItem of featureRuleNode.selectList) {
        const selItem = find(featureRuleNode.attributes, (obj) => {
          return listItem.enumVal2 === obj.attributeName
        })
        if (selItem) {
          listItem.disable = 1;
        } else {
          listItem.disable = 0;
        }
      }

      const attributeNameArray = [];
      for (const option of featureRuleNode.attributes) {
        attributeNameArray.push(option.attributeName);
      }
      const isIntersection = intersection(disableArray, attributeNameArray).length > 0;
      if (isIntersection) {
        for (const str of disableArray) {
          const selItem = find(featureRuleNode.selectList, (item) => {
            return str === item.enumVal2;
          })
          selItem.disable = 1;
        }
      }
    },

    // 子节点添加
    addChildByFeatureRule(childrenNodes) {
      childrenNodes.push({
        childNodeVal: '',
        // 子节点中的属性下拉框数据
        childAttrSelList: [],
        childAttributes: [{
          childAttrName: '',
          childAttrVal: '',
        }]
      })
    },
    // 子节点删除
    deleteChildByFeatureRule(childrenNodes, index) {
      childrenNodes.splice(index, 1);
    },
    // 子节点内的树形添加
    gandeAddByFeatureRule(childAttributes) {
      /*const upItem = childAttributes[childAttributes.length - 1];
      if(!upItem.childAttrName || upItem.childAttrVal === '') {
        this.$message.warning('请将子节点内容完善');
        return;
      }*/
      childAttributes.push({
        key: new Date().getTime() + 8,
        childAttrName: '',
        childAttrVal: '',
      })
    },
    gandeDeleteByFeatureRule(childAttributes, index) {
      childAttributes.splice(index, 1);
    },
    ganDeChildNodeChange(selVal, childrenNodes) {
      const options = getOptions(selVal);
      childrenNodes.childAttrSelList = cloneDeep(options);
      childrenNodes.childAttributes = [{
        childAttrName: '',
        childAttrVal: '',
      }]
    },
    ganDeChildAttrChange(selVal, attrNode) {
      attrNode.childAttrVal = '';
      if (selVal === 'type') {
        attrNode.childAttrVal = 'dp'
      }
    },

    /*添加特征规则节点相关方法------*/

    /* 增加、删除表单项目相关方法~~~~~~~~~ */


    setRuleContent() {

      const {protocol, featureAttributeNodes, featureActionNodes, featureRuleNodes} = this.dataForm;
      if(!protocol){
        return;
      }
      console.log(this.getCustomFeatureJson())
      let protocolString = '';
      for (const ruleItem of featureAttributeNodes) {
        if (ruleItem.attributeName) {
          const val = ruleItem.attributeVal === true ? 1 : ruleItem.attributeVal;
          protocolString += `${ruleItem.attributeName}="${val}" `;
        }
      }

      let actionString = '';
      for (const ruleItem of featureActionNodes) {
        if (ruleItem.attributeName) {
          actionString += `${ruleItem.attributeName}="${ruleItem.attributeVal}" `;
        }

      }
      const action = `<action ${actionString}></action>`;

      let ciString = '';

      function getGanSonStr(childrenNodes) {
        if(!childrenNodes){
          return  ''
        }
        let childString = ''
        for (const gItem of childrenNodes) {
          if (gItem.childNodeVal === '') {
            continue;
          }
          childString += `<${gItem.childNodeVal}`;
          for (const attrGItem of gItem.childAttributes) {
            if (attrGItem.childAttrName) {
              childString += ` ${attrGItem.childAttrName}="${attrGItem.childAttrVal}" `;
            }
          }

          childString += `></${gItem.childNodeVal}>`;
        }
        return childString;
      }

      for (const ruleItem of featureRuleNodes) {
        ciString += `<${ruleItem.nodeVal}`;
        for (const attrItem of ruleItem.attributes) {
          if (attrItem.attributeName) {
            ciString += ` ${attrItem.attributeName}="${attrItem.attributeVal}" `;
          }
        }

        ciString += `>${getGanSonStr(ruleItem.childrenNodes)}</${ruleItem.nodeVal}>`;
      }

      const content = `<${protocol} ${protocolString}>${action}${ciString}</${protocol}>`
      this.dataForm.customFeature = content;
    }
  }
};
</script>

<style>
.page-view {
  width: 900px;
  margin: 0 auto;
}

.collapse-area .el-collapse-item__header {
  border: none;
}

.collapse-area .el-collapse-item__arrow {
  color: #409EFF;
}

.collapse-area .el-collapse-item__header > div {
  width: 100%;
  text-align: right;
  color: #409EFF;
  padding-right: 5px;
  font-size: 14px;
}

.protocol-area {
  display: flex;
  margin-bottom: 20px;
}

.protocol-box {
  flex: 1;
  padding: 20px 20px 20px 0;
  border: 1px dashed #c4c0c0;
  border-radius: 5px;
  /*margin-bottom: 20px;*/
}

.protocol-attr-box {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}

.protocol-attr-box:last-of-type {
  margin-bottom: 0;
}

.protocol-attr-box .child:first-of-type {
  margin: 0;
}

.protocol-attr-box .child:nth-of-type(2) {
  height: 1px;
  width: 30px;
  background: #ccc;
}

.protocol-attr-box .child:nth-of-type(3) {
  flex: 1;
  margin: 0;
}

.protocol-attr-box .child:nth-of-type(3) > div {
  margin-left: 0 !important;
}

.protocol-attr-box .child:last-of-type {
  padding-left: 20px;
}


.child-box {
  width: 800px;
  height: auto;
  border: 1px dashed #c4c0c0;
  border-radius: 5px;
  padding: 20px;
  margin-left: 80px;
}

.child-box .el-form-item__content {
  margin: 0 !important;
}

.child-title {
  width: 800px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  color: #606266;
  margin: 20px 0 10px 0;
  padding-left: 80px;
}

.grandson-area {

  display: flex;
  align-items: center;
  margin-left: 80px;
}

.grandson-box {
  flex: 1;
  padding: 20px;
  border: 1px dashed #c4c0c0;
  border-radius: 5px;
  margin-bottom: 10px;
  display: flex;
}

.grandson-box .el-form-item {
  margin-bottom: 0 !important;
}

.grandson-box .el-form-item__content {
  margin: 0 !important;
}

</style>